package im.oen.boot.common.utils;

import im.oen.boot.common.constant.Charsets;
import im.oen.boot.common.constant.OenCode;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>描述：暂无描述信息</p>
 *
 * <p>创建时间：2021-09-22 11:25</p>
 * <p>更新时间：暂无</p>
 *
 * @author Kevin.Xu
 * @version 1.0
 */
public class Convert {
    public static Integer min(Integer... nums) {
        if (nums == null) {
            throw OenCode.PARAMETER_IS_EMPTY.exception("nums");
        }
        Integer min = Integer.MAX_VALUE;
        for (Integer num : nums) {
            if (num == null) {
                continue;
            }
            if (num < min) {
                min = num;
            }
        }
        return min;
    }

    public static Integer max(Integer... nums) {
        if (nums == null) {
            throw OenCode.PARAMETER_IS_EMPTY.exception("nums");
        }
        Integer max = Integer.MIN_VALUE;
        for (Integer num : nums) {
            if (num == null) {
                continue;
            }
            if (num > max) {
                max = num;
            }
        }
        return max;
    }

    public static Double min(Double... nums) {
        if (nums == null) {
            throw OenCode.PARAMETER_IS_EMPTY.exception("nums");
        }
        Double min = Double.MAX_VALUE;
        for (Double num : nums) {
            if (num == null) {
                continue;
            }
            if (num < min) {
                min = num;
            }
        }
        return min;
    }

    public static Double max(Double... nums) {
        if (nums == null) {
            throw OenCode.PARAMETER_IS_EMPTY.exception("nums");
        }
        Double max = Double.MIN_VALUE;
        for (Double num : nums) {
            if (num == null) {
                continue;
            }
            if (num > max) {
                max = num;
            }
        }
        return max;
    }

    public static Long min(Long... nums) {
        if (nums == null) {
            throw OenCode.PARAMETER_IS_EMPTY.exception("nums");
        }
        Long min = Long.MAX_VALUE;
        for (Long num : nums) {
            if (num == null) {
                continue;
            }
            if (num < min) {
                min = num;
            }
        }
        return min;
    }

    public static Long max(Long... nums) {
        if (nums == null) {
            throw OenCode.PARAMETER_IS_EMPTY.exception("nums");
        }
        Long max = Long.MIN_VALUE;
        for (Long num : nums) {
            if (num == null) {
                continue;
            }
            if (num > max) {
                max = num;
            }
        }
        return max;
    }

    public static String toStr(byte[] bytes) {
        if (Checker.isEmpty(bytes)) {
            return null;
        }
        return new String(bytes, Charsets.UTF_8);
    }

    /**
     * @param obj
     * @return default null
     */
    public static String toStr(Object obj) {
        if (Checker.isEmpty(obj)) {
            return null;
        }
        return String.valueOf(obj);
    }

    public static Boolean toBoolean(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return Boolean.FALSE;
        }
        return Boolean.valueOf(value);
    }

    /**
     * @param obj
     * @return default 0
     */
    public static Integer toInt(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return 0;
        }
        return Integer.valueOf(value);
    }

    public static Short toShort(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return 0;
        }
        return Short.valueOf(value);
    }

    public static Byte toByte(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return 0;
        }
        return Byte.valueOf(value);
    }

    /**
     * @param obj
     * @return default 0
     */
    public static Long toLong(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return 0L;
        }
        return Long.valueOf(value);
    }

    /**
     * @param obj
     * @return default 0
     */
    public static BigDecimal toBigDecimal(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(value);
    }

    public static Double toDouble(Object obj) {
        String value = toStr(obj);
        if (Checker.isEmpty(value)) {
            return 0.0;
        }
        return Double.valueOf(value);
    }

    public static <K, V> List<V> fetchByKey(K[] keys, Map<K, V> values) {
        if (Checker.isEmpty(keys) || Checker.isEmpty(values)) {
            return null;
        }
        return fetchByKey(Arrays.asList(keys), values);
    }

    public static <K, V> List<V> fetchByKey(List<K> keys, Map<K, V> values) {
        if (Checker.isEmpty(keys) || Checker.isEmpty(values)) {
            return null;
        }
        List<V> list = new ArrayList<>(keys.size());
        for (K k : keys) {
            V v = values.get(k);
            if (Checker.isNotEmpty(v)) {
                list.add(v);
            }
        }
        return list;
    }

    public static <E extends Serializable> E[] merge(E[] e1, E[] e2, Class<E> type) {
        if (Checker.isEmpty(e1)) {
            return e2;
        }
        if (Checker.isEmpty(e2)) {
            return e1;
        }
        E[] res = (E[]) Array.newInstance(type, e1.length + e2.length);
        int idx = 0;
        for (E e : e1) {
            res[idx] = e;
            idx++;
        }
        for (E e : e2) {
            res[idx] = e;
            idx++;
        }
        return res;
    }

    public static <E extends Serializable> E[] mergeWithoutDuplication(E[] e1, E[] e2, Class<E> type) {
        if (Checker.isEmpty(e1)) {
            return e2;
        }
        if (Checker.isEmpty(e2)) {
            return e1;
        }
        Set<E> sets = new HashSet<>();
        for (E e : e1) {
            sets.add(e);
        }
        for (E e : e2) {
            sets.add(e);
        }

        E[] res = (E[]) Array.newInstance(type, sets.size());
        int idx = 0;
        for (E e : sets) {
            res[idx] = e;
            idx++;
        }
        return res;
    }
}